use serde::{Deserialize, Serialize};
use sqlx::mysql::MySqlPool;
use sqlx::{FromRow, MySql, Pool};
use tauri::{path::BaseDirectory, AppHandle, Manager};
use tauri_plugin_sql::{Migration, MigrationKind};

#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
    pub database: DatabaseConfig,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DatabaseConfig {
    pub mysql_url: String,
}

#[derive(Debug, Serialize, Deserialize, FromRow)]
pub struct User {
    pub id: i32,
    pub name: String,
    pub email: String,
}

pub async fn setup_database(app_handle: AppHandle) -> Result<(), String> {
    let file_name = if cfg!(debug_assertions) {
        "config-dev.json"
    } else {
        "config-prod.json"
    };
    
    // 解析配置文件路径
    let config_path = app_handle.path().resolve(file_name, BaseDirectory::Resource)
        .map_err(|e| format!("无法解析配置文件路径: {}", e))?;
    
    println!("配置文件路径: {:?}", config_path);

    // 读取配置文件
    let file = std::fs::File::open(&config_path)
        .map_err(|e| format!("无法打开配置文件: {}", e))?;
    
    let config: Config = serde_json::from_reader(file)
        .map_err(|e| format!("无法解析配置文件: {}", e))?;
    
    // 创建迁移数组
    let migrations = vec![
        Migration {
            version: 1,
            description: "create initial tables",
            sql: "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL);",
            kind: MigrationKind::Up,
        },
    ];
    
    // 克隆变量以便在异步任务中使用
    let mysql_url = config.database.mysql_url.clone();
    
    // 创建数据库连接池
    let pool = MySqlPool::connect(&mysql_url).await
        .map_err(|e| format!("无法连接数据库: {}", e))?;
    
    println!("Database connection pool created successfully");
    
    // 执行迁移
    for migration in &migrations {
        println!("Executing migration: {}", migration.description);
        sqlx::query(migration.sql).execute(&pool).await
            .map_err(|e| format!("迁移失败: {}", e))?;
    }
    
    println!("Migrations completed successfully");
    
    // 使用app_handle管理连接池
    app_handle.manage(pool);
    
    Ok(())
}

// 用户相关操作
#[tauri::command]
pub async fn get_users(pool: tauri::State<'_, Pool<MySql>>) -> Result<String, String> {
    let users = sqlx::query_as::<_, User>("SELECT id, name, email FROM users ORDER BY id")
        .fetch_all(&*pool)
        .await
        .map_err(|e| e.to_string())?;

    serde_json::to_string(&users).map_err(|e| e.to_string())
}

#[tauri::command]
pub async fn add_user(
    pool: tauri::State<'_, Pool<MySql>>,
    name: String,
    email: String,
) -> Result<(), String> {
    sqlx::query("INSERT INTO users (name, email) VALUES (?, ?)")
        .bind(name)
        .bind(email)
        .execute(&*pool)
        .await
        .map_err(|e| e.to_string())?;

    Ok(())
}

#[tauri::command]
pub async fn update_user(
    pool: tauri::State<'_, Pool<MySql>>,
    id: i32,
    name: String,
    email: String,
) -> Result<(), String> {
    sqlx::query("UPDATE users SET name = ?, email = ? WHERE id = ?")
        .bind(name)
        .bind(email)
        .bind(id)
        .execute(&*pool)
        .await
        .map_err(|e| e.to_string())?;

    Ok(())
}

#[tauri::command]
pub async fn delete_user(pool: tauri::State<'_, Pool<MySql>>, id: i32) -> Result<(), String> {
    sqlx::query("DELETE FROM users WHERE id = ?")
        .bind(id)
        .execute(&*pool)
        .await
        .map_err(|e| e.to_string())?;

    Ok(())
} 